package zero.tech.redis.config;

import java.util.HashSet;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;
@Configuration
@ConfigurationProperties(prefix = "redis.queue")
@ConditionalOnProperty(prefix ="redis.queue",name="enable",havingValue = "true",matchIfMissing = false )
public class RedisQueueConfig {
	private String mode;
	private Boolean enable;
	private String pwd;
	private int database;
	private int maxTotal;
	private int maxIdle;
	private int minIdle;
	private int maxWaitMillis;
	
	
	private String host;
	private Integer port;
	
	private String mastername;
	private String sentinelnodes;
	
	private String clusternodes;
	private String clusterconnectiontimeout;
	private String clustersotimeout;
	private String clustermaxattempts;
	
	public class QueueMode{
		public static final String STANDALONE = "standalone";
		public static final String SENTINEL = "sentinel";
		public static final String CLUSTER = "cluster";
	}
	
	@Bean(name = "jedisQueuePool")
	@ConditionalOnMissingBean(name="jedisSentinelQueuePool")
	@ConditionalOnProperty(prefix ="redis.queue",name="mode",havingValue = QueueMode.STANDALONE,matchIfMissing = false )
	public JedisPool jedisQueuePool(JedisPoolConfig config) {
		return new JedisPool(config, host, port, 0, pwd,database);
	}
	@Bean(name = "jedisSentinelQueuePool")
	@ConditionalOnMissingBean(name="jedisQueueCluster")
	@ConditionalOnProperty(prefix ="redis.queue",name="mode",havingValue = QueueMode.SENTINEL)
	public JedisSentinelPool jedisSentinelQueuePool(JedisPoolConfig config) {
		 String[] sentinels=sentinelnodes.split(",");
         Set<String> addresses=new HashSet<>();
         for(int i=0;i<sentinels.length;i++) {
        	 addresses.add("redis://"+sentinels[i]);
         }
		return new JedisSentinelPool(mastername, addresses, config, 0, pwd, database);
	}
	@Bean(name = "jedisQueueCluster")
	@ConditionalOnProperty(prefix ="redis.queue",name="mode",havingValue = QueueMode.CLUSTER)
	public JedisCluster jedisQueueCluster(JedisPoolConfig config) {
		String[] clusters=clusternodes.split(",");
	    Set<HostAndPort> addresses=new HashSet<>();
	    for(int i=0;i<clusters.length;i++) {
		    String cluster=clusters[i];
		    String[] strs=cluster.split(":");
		    HostAndPort hostAndPort=new HostAndPort(strs[0],Integer.valueOf(strs[1]));
		    addresses.add(hostAndPort);
	    }
	    return new JedisCluster(addresses, 
	    		StringUtils.isBlank(clusterconnectiontimeout)?2000:Integer.valueOf(clusterconnectiontimeout),
	    				StringUtils.isBlank(clustersotimeout)?2000:Integer.valueOf(clustersotimeout),
	    						StringUtils.isBlank(clustermaxattempts)?5:Integer.valueOf(clustermaxattempts),
	    						pwd, 
	    						config
	    );
	}

	@Bean
	public JedisPoolConfig poolConfig() {
		JedisPoolConfig config = new JedisPoolConfig();
		config.setMaxTotal(maxTotal);
		config.setMaxIdle(maxIdle);
		config.setMinIdle(minIdle);
		config.setMaxWaitMillis(maxWaitMillis);
		config.setTestOnBorrow(true);
		config.setTestWhileIdle(true);
		config.setTestOnReturn(true);
		return config;
	}
	public String getMode() {
		return mode;
	}
	public void setMode(String mode) {
		this.mode = mode;
	}
	public Boolean getEnable() {
		return enable;
	}
	public void setEnable(Boolean enable) {
		this.enable = enable;
	}
	public int getDatabase() {
		return database;
	}
	public void setDatabase(int database) {
		this.database = database;
	}
	public int getMaxTotal() {
		return maxTotal;
	}
	public void setMaxTotal(int maxTotal) {
		this.maxTotal = maxTotal;
	}
	public int getMaxIdle() {
		return maxIdle;
	}
	public void setMaxIdle(int maxIdle) {
		this.maxIdle = maxIdle;
	}
	public int getMinIdle() {
		return minIdle;
	}
	public void setMinIdle(int minIdle) {
		this.minIdle = minIdle;
	}
	public int getMaxWaitMillis() {
		return maxWaitMillis;
	}
	public void setMaxWaitMillis(int maxWaitMillis) {
		this.maxWaitMillis = maxWaitMillis;
	}
	public String getHost() {
		return host;
	}
	public void setHost(String host) {
		this.host = host;
	}
	public Integer getPort() {
		return port;
	}
	public void setPort(Integer port) {
		this.port = port;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
	public String getMastername() {
		return mastername;
	}
	public void setMastername(String mastername) {
		this.mastername = mastername;
	}
	public String getSentinelnodes() {
		return sentinelnodes;
	}
	public void setSentinelnodes(String sentinelnodes) {
		this.sentinelnodes = sentinelnodes;
	}
	public String getClusternodes() {
		return clusternodes;
	}
	public void setClusternodes(String clusternodes) {
		this.clusternodes = clusternodes;
	}
	public String getClusterconnectiontimeout() {
		return clusterconnectiontimeout;
	}
	public void setClusterconnectiontimeout(String clusterconnectiontimeout) {
		this.clusterconnectiontimeout = clusterconnectiontimeout;
	}
	public String getClustersotimeout() {
		return clustersotimeout;
	}
	public void setClustersotimeout(String clustersotimeout) {
		this.clustersotimeout = clustersotimeout;
	}
	public String getClustermaxattempts() {
		return clustermaxattempts;
	}
	public void setClustermaxattempts(String clustermaxattempts) {
		this.clustermaxattempts = clustermaxattempts;
	}
}
